﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Threading;
using ShredTheLog.Model;
using ShredTheLog.WpfClient.Properties;
using System.Globalization;
using System.ComponentModel;
using System.Windows.Markup;
using System.Reflection;
using System.Threading;
using ShredTheLog.Translation;
using System.Diagnostics;
using System.ComponentModel.Composition.Hosting;
using ShredTheLog.Common.MVVM;
using ShredTheLog.Api.DataContracts;
using ShredTheLog.Plugins;
using ShredTheLog.Controls;
using ShredTheLog.Api;
using ShredTheLog.ViewModels;
using ShredTheLog.Views;
using System.ComponentModel.Composition;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
using System.Text;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace ShredTheLog.WpfClient
{
    public partial class App : Application
    {
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            Trace.WriteLineIf(TraceFlags.Initialization, "Initializing...");

            FrameworkElement.LanguageProperty.OverrideMetadata(
                typeof(FrameworkElement),
                new FrameworkPropertyMetadata(XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));

            TextOptions.TextFormattingModeProperty.OverrideMetadata(
                typeof(FrameworkElement),
                new FrameworkPropertyMetadata(TextFormattingMode.Display));

            FrameworkElement.UseLayoutRoundingProperty.OverrideMetadata(
                typeof(Control),
                new FrameworkPropertyMetadata(true));
            FrameworkElement.UseLayoutRoundingProperty.OverrideMetadata(
                typeof(Popup),
                new FrameworkPropertyMetadata(true));

            FrameworkElement.SnapsToDevicePixelsProperty.OverrideMetadata(
                typeof(Control),
                new FrameworkPropertyMetadata(true));
            FrameworkElement.SnapsToDevicePixelsProperty.OverrideMetadata(
                typeof(Popup),
                new FrameworkPropertyMetadata(true));

            _shredServices = new ShredServices(
                this.Resources,
                () => ShredTheLog.WpfClient.Properties.Settings.Default.ShredSettings,
                serializedSettings => { ShredTheLog.WpfClient.Properties.Settings.Default.ShredSettings = serializedSettings; ShredTheLog.WpfClient.Properties.Settings.Default.Save(); });

            string appPath = System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            Trace.WriteLineIf(TraceFlags.Initialization, String.Format("Application path: {0}", appPath));
            var catalog = new DirectoryCatalog(appPath);
            Trace.WriteLineIf(TraceFlags.Initialization, "Parts in catalog: ");
            catalog.Parts.ForEach(i => Trace.WriteLineIf(TraceFlags.Initialization, i.ToString()));
            Trace.WriteLineIf(TraceFlags.Initialization, String.Format("Parts count: {0:d}", catalog.Parts.Count()));

            var compositionContainer = new CompositionContainer(catalog);
            compositionContainer.ComposeParts(_shredServices);
            ViewModelBase.CompositionContainer = compositionContainer;
            Globals.CompositionContainer = compositionContainer;

            _shredServices.Run();
        }

        private ShredServices _shredServices;

        private void Application_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
        {
            if (e.Exception is Win32Exception && ((Win32Exception)e.Exception).NativeErrorCode == 0)
            {
                // Похоже на проявляющийся в зависимости от фазы Луны глюк фреймворка, 
                // который вылазит при старте приложения.
                // Скорее всего связан с кривым post 3.5 SP1 обновлением фреймворка, 
                // а еще точнее со Splash Screens.
                // На вид не заметно, чтобы это серьезно мешало дальнейшей работе приложения.
                // Не уверен, что splash screen будет корректно убираться с экрана,
                // возможно сюда еще придется поставить дополнительный вызов перерисовки или
                // нечто вроде того...
            }
            else
            {
                if (_shredServices != null)
                    _shredServices.ShowError(e.Exception);
                else
                    MessageBox.Show(e.Exception.ToString());
            }
            e.Handled = true;
        }
    }
}
